package com.example.hotHub.service.impl;

import com.example.hotHub.model.NormalHotSearch;
import com.example.hotHub.service.WeiboHotPointService;
import com.example.hotHub.utils.RestTemplateUtil;
import com.example.hotHub.utils.SimpleMap;
import com.example.hotHub.utils.client.WeiboClient;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.util.UriEncoder;

import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import static com.example.hotHub.cnst.CommonConst.DEFAULT_IMAGE_URL;

@Slf4j
@Service
public class WeiboHotPointServiceImpl implements WeiboHotPointService {

    @Autowired
    private ExecutorService threadPoolExecutor;

    private SimpleMap getWeiboTid() throws IOException {
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            String url = "https://passport.weibo.com/visitor/genvisitor?cb=gen_callback";
            HttpGet request = new HttpGet(url);
            request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
            CloseableHttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity httpEntity = response.getEntity();
                String html = EntityUtils.toString(httpEntity, "utf-8");
                html = html.replace("window.gen_callback && gen_callback({\"retcode\":20000000,\"msg\":\"succ\",\"data\":", "");
                html = html.replace("});", "");
                SimpleMap tid = SimpleMap.parse(html, SimpleMap.class);
                return tid;
            }
        } catch (Exception ex) {
            return getWeiboTid();
        }
        return SimpleMap.build();
    }

    @SneakyThrows
    private SimpleMap getCookie() {
        try {
            SimpleMap weiboTid = getWeiboTid();
            String url = "https://passport.weibo.com/visitor/visitor?a=incarnate&t=" + weiboTid.getString("tid") + "&w=" + (weiboTid.getBoolean("new_tid") ? 3 : 2) + "&c=100&cb=cross_domain&from=weibo";

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet request = new HttpGet(url);
            request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
            CloseableHttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity httpEntity = response.getEntity();
                String html = EntityUtils.toString(httpEntity, "utf-8");
                html = html.replace("window.cross_domain && cross_domain({\"retcode\":20000000,\"msg\":\"succ\",\"data\":", "");
                html = html.replace("});", "");
                SimpleMap cookieMap = SimpleMap.parse(html, SimpleMap.class);
                return cookieMap;
            }
            return SimpleMap.build();
        } catch (Exception ex) {
            return getCookie();
        }
    }

    @SneakyThrows
    private NormalHotSearch getWeiboDetail(NormalHotSearch normalHotSearch) {
        try {
            String html = new WeiboClient().get(normalHotSearch.getUrl());
            Document document = Jsoup.parse(html);
            Element element = document.getElementById("pl_topic_header")
                    .getElementsByClass("spic").get(0)
                    .select("img").get(0);

            String describe = document.getElementsByClass("card card-topic-lead s-pg16").get(0)
                    .select("p").get(0)
                    .text();

            normalHotSearch.setImageUrl(element.attr("src"))
                    .setDescribe(describe.replace("导语：", ""));
            return normalHotSearch;
        } catch (Exception ex) {
            log.debug("获取微博详情失败");
            return normalHotSearch.setImageUrl(DEFAULT_IMAGE_URL).setDescribe(normalHotSearch.getTitle());
        }
    }

    @Override
    public List<NormalHotSearch> getHotPointList() {
        RestTemplateUtil restTemplateUtil = new RestTemplateUtil();
        SimpleMap response = restTemplateUtil.doGet("https://weibo.com/ajax/statuses/hot_band", null, null, SimpleMap.class);
        List<SimpleMap> list = response.getMap("data")
                .getList("band_list", SimpleMap.class);
        List<NormalHotSearch> normalHotSearchList = new CopyOnWriteArrayList<>();

        int size = list.size();
        CountDownLatch latch = new CountDownLatch(size);

        long start = System.currentTimeMillis();
        for (SimpleMap element : list) {
            threadPoolExecutor.execute(() -> {
                try {
                    if (element.getString("ad_type") != null) {
                        log.info("跳过商业投放");
                        return;
                    }

                    String note = element.getString("note");
                    String topic_url = "https://s.weibo.com/weibo?q=" + UriEncoder.encode(element.getString("word_scheme"));
                    Integer hotValue = element.getInt("num");
                    NormalHotSearch normalHotSearch = new NormalHotSearch();
                    normalHotSearch.setTitle(note)
                            .setUrl(topic_url)
                            .setHotValue(hotValue);
                    normalHotSearch = getWeiboDetail(normalHotSearch);
                    normalHotSearchList.add(normalHotSearch);
                } catch (Exception ex) {

                } finally {
                    latch.countDown();
                }
            });
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        long end = System.currentTimeMillis();
        System.out.println("=====================================================================================");
        System.out.println("use time:" + (end - start));

        List<NormalHotSearch> finalNormalHotSearchList = normalHotSearchList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        log.debug("成功爬取微博热点: {}", finalNormalHotSearchList);


        return finalNormalHotSearchList;
    }
}
